// 应用启动速度优化服务

export interface BootstrapMetrics {
  startTime: number;
  domContentLoadedTime?: number;
  loadTime?: number;
  firstPaintTime?: number;
  firstContentfulPaintTime?: number;
  timeToInteractive?: number;
  criticalResourcesLoaded?: number;
  totalResourcesLoaded?: number;
  initialBundleSize?: number;
  customMetrics: { [key: string]: number };
}

export interface DeferredTask {
  name: string;
  priority: number;
  condition?: () => boolean;
  initialize: () => Promise<void>;
  timeout?: number;
  dependencies?: string[];
}

export interface CacheStrategy {
  enableServiceWorker: boolean;
  enableStaticCaching: boolean;
  enableDynamicCaching: boolean;
  cacheVersion: string;
  maxCacheSize: number; // MB
}

export interface BootstrapConfig {
  criticalComponents: string[];
  preloadRoutes: string[];
  deferredInitialization: DeferredTask[];
  cacheStrategy: CacheStrategy;
  performanceTargets: {
    maxStartupTime: number; // ms
    maxTimeToInteractive: number; // ms
    maxFirstPaint: number; // ms
  };
}

/**
 * 启动速度优化服务
 */
export class StartupOptimizationService {
  private metrics: BootstrapMetrics;
  private config: BootstrapConfig;
  private deferredTasks: Map<string, DeferredTask> = new Map();
  private completedTasks: Set<string> = new Set();
  private isInitialized = false;
  private startupPhase: 'loading' | 'critical' | 'deferred' | 'complete' = 'loading';

  constructor(config: BootstrapConfig) {
    this.config = config;
    this.metrics = {
      startTime: performance.now(),
      customMetrics: {}
    };
    
    this.initializePerformanceObserver();
  }

  /**
   * 初始化性能观察器
   */
  private initializePerformanceObserver(): void {
    try {
      // 观察性能指标
      if ('PerformanceObserver' in window) {
        const observer = new PerformanceObserver((list) => {
          for (const entry of list.getEntries()) {
            this.recordPerformanceEntry(entry);
          }
        });

        observer.observe({ entryTypes: ['paint', 'navigation', 'resource'] });
      }

      // 监听 DOM 事件
      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
          this.metrics.domContentLoadedTime = performance.now() - this.metrics.startTime;
          console.log(`[启动优化] DOM 内容加载完成: ${this.metrics.domContentLoadedTime.toFixed(2)}ms`);
        });
      }

      window.addEventListener('load', () => {
        this.metrics.loadTime = performance.now() - this.metrics.startTime;
        console.log(`[启动优化] 页面加载完成: ${this.metrics.loadTime.toFixed(2)}ms`);
        this.checkStartupTargets();
      });

    } catch (error) {
      console.error('[启动优化] 性能观察器初始化失败:', error);
    }
  }

  /**
   * 记录性能条目
   */
  private recordPerformanceEntry(entry: PerformanceEntry): void {
    switch (entry.entryType) {
      case 'paint':
        if (entry.name === 'first-paint') {
          this.metrics.firstPaintTime = entry.startTime;
          console.log(`[启动优化] 首次绘制: ${entry.startTime.toFixed(2)}ms`);
        } else if (entry.name === 'first-contentful-paint') {
          this.metrics.firstContentfulPaintTime = entry.startTime;
          console.log(`[启动优化] 首次内容绘制: ${entry.startTime.toFixed(2)}ms`);
        }
        break;

      case 'navigation':
        // 记录导航性能指标
        break;

      case 'resource':
        // 记录资源加载性能
        this.metrics.totalResourcesLoaded = (this.metrics.totalResourcesLoaded || 0) + 1;
        break;
    }
  }

  /**
   * 开始应用初始化
   */
  async initialize(): Promise<void> {
    if (this.isInitialized) {
      console.warn('[启动优化] 服务已初始化');
      return;
    }

    console.log('[启动优化] 开始应用初始化');
    this.recordCustomMetric('initialization_start', performance.now());

    try {
      // 阶段1: 加载关键组件
      await this.loadCriticalComponents();

      // 阶段2: 设置延迟任务
      this.setupDeferredTasks();

      // 阶段3: 初始化缓存策略
      await this.initializeCacheStrategy();

      // 阶段4: 预加载关键路由
      this.preloadCriticalRoutes();

      this.startupPhase = 'critical';
      this.isInitialized = true;
      
      this.recordCustomMetric('initialization_complete', performance.now());
      const initTime = this.metrics.customMetrics.initialization_complete - this.metrics.customMetrics.initialization_start;
      console.log(`[启动优化] 初始化完成: ${initTime.toFixed(2)}ms`);

      // 开始执行延迟任务
      this.executeDeferredTasks();

    } catch (error) {
      console.error('[启动优化] 初始化失败:', error);
      throw error;
    }
  }

  /**
   * 加载关键组件
   */
  private async loadCriticalComponents(): Promise<void> {
    const startTime = performance.now();
    console.log('[启动优化] 加载关键组件');

    try {
      // 并行加载关键组件
      const loadPromises = this.config.criticalComponents.map(async (componentName) => {
        try {
          console.log(`[启动优化] 加载关键组件: ${componentName}`);
          // 这里应该是实际的组件加载逻辑
          await this.loadComponent(componentName);
          return componentName;
        } catch (error) {
          console.error(`[启动优化] 关键组件 ${componentName} 加载失败:`, error);
          throw error;
        }
      });

      const loadedComponents = await Promise.all(loadPromises);
      this.metrics.criticalResourcesLoaded = loadedComponents.length;

      const loadTime = performance.now() - startTime;
      this.recordCustomMetric('critical_components_load_time', loadTime);
      console.log(`[启动优化] 关键组件加载完成: ${loadTime.toFixed(2)}ms`);

    } catch (error) {
      console.error('[启动优化] 关键组件加载失败:', error);
      throw error;
    }
  }

  /**
   * 加载单个组件（模拟）
   */
  private async loadComponent(_componentName: string): Promise<void> {
    // 模拟组件加载时间
    const mockLoadTime = Math.random() * 100 + 50; // 50-150ms
    await new Promise(resolve => setTimeout(resolve, mockLoadTime));
  }

  /**
   * 设置延迟任务
   */
  private setupDeferredTasks(): void {
    console.log('[启动优化] 设置延迟任务');

    this.config.deferredInitialization.forEach(task => {
      this.deferredTasks.set(task.name, task);
    });

    // 按优先级排序
    const sortedTasks = Array.from(this.deferredTasks.values())
      .sort((a, b) => b.priority - a.priority);

    console.log(`[启动优化] 已设置 ${sortedTasks.length} 个延迟任务`);
  }

  /**
   * 执行延迟任务
   */
  private async executeDeferredTasks(): Promise<void> {
    console.log('[启动优化] 开始执行延迟任务');
    this.startupPhase = 'deferred';

    const tasks = Array.from(this.deferredTasks.values())
      .sort((a, b) => b.priority - a.priority);

    // 等待关键初始化完成后再执行延迟任务
    await this.waitForIdleTime(1000);

    for (const task of tasks) {
      try {
        await this.executeDeferredTask(task);
      } catch (error) {
        console.error(`[启动优化] 延迟任务 ${task.name} 执行失败:`, error);
      }
    }

    this.startupPhase = 'complete';
    console.log('[启动优化] 所有延迟任务执行完成');
  }

  /**
   * 执行单个延迟任务
   */
  private async executeDeferredTask(task: DeferredTask): Promise<void> {
    // 检查条件
    if (task.condition && !task.condition()) {
      console.log(`[启动优化] 延迟任务 ${task.name} 条件不满足，跳过`);
      return;
    }

    // 检查依赖
    if (task.dependencies) {
      const unmetDependencies = task.dependencies.filter(dep => !this.completedTasks.has(dep));
      if (unmetDependencies.length > 0) {
        console.log(`[启动优化] 延迟任务 ${task.name} 依赖未满足: ${unmetDependencies.join(', ')}`);
        return;
      }
    }

    console.log(`[启动优化] 执行延迟任务: ${task.name}`);
    const startTime = performance.now();

    try {
      // 设置超时
      const timeoutPromise = task.timeout ? 
        new Promise((_, reject) => setTimeout(() => reject(new Error('Task timeout')), task.timeout)) :
        new Promise(() => {}); // 永不resolve

      await Promise.race([
        task.initialize(),
        timeoutPromise
      ]);

      const executeTime = performance.now() - startTime;
      this.recordCustomMetric(`deferred_task_${task.name}`, executeTime);
      this.completedTasks.add(task.name);

      console.log(`[启动优化] 延迟任务 ${task.name} 完成: ${executeTime.toFixed(2)}ms`);

    } catch (error) {
      console.error(`[启动优化] 延迟任务 ${task.name} 执行失败:`, error);
    }
  }

  /**
   * 等待空闲时间
   */
  private waitForIdleTime(minIdleTime: number = 500): Promise<void> {
    return new Promise(resolve => {
      if ('requestIdleCallback' in window) {
        requestIdleCallback(() => resolve(), { timeout: minIdleTime * 2 });
      } else {
        setTimeout(resolve, minIdleTime);
      }
    });
  }

  /**
   * 初始化缓存策略
   */
  private async initializeCacheStrategy(): Promise<void> {
    console.log('[启动优化] 初始化缓存策略');

    if (!this.config.cacheStrategy.enableServiceWorker) {
      return;
    }

    try {
      if ('serviceWorker' in navigator) {
        console.log('[启动优化] 注册 Service Worker');
        // 这里应该是实际的Service Worker注册逻辑
        await this.registerServiceWorker();
      }
    } catch (error) {
      console.error('[启动优化] 缓存策略初始化失败:', error);
    }
  }

  /**
   * 注册 Service Worker（模拟）
   */
  private async registerServiceWorker(): Promise<void> {
    // 模拟Service Worker注册
    await new Promise(resolve => setTimeout(resolve, 100));
    console.log('[启动优化] Service Worker 注册完成');
  }

  /**
   * 预加载关键路由
   */
  private preloadCriticalRoutes(): void {
    console.log('[启动优化] 预加载关键路由');

    this.config.preloadRoutes.forEach(route => {
      // 这里应该是实际的路由预加载逻辑
      console.log(`[启动优化] 预加载路由: ${route}`);
    });
  }

  /**
   * 记录自定义指标
   */
  recordCustomMetric(name: string, value: number): void {
    this.metrics.customMetrics[name] = value;
    console.log(`[启动优化] 记录指标 ${name}: ${value.toFixed(2)}ms`);
  }

  /**
   * 检查启动目标
   */
  private checkStartupTargets(): void {
    const { performanceTargets } = this.config;
    const issues: string[] = [];

    if (this.metrics.loadTime && this.metrics.loadTime > performanceTargets.maxStartupTime) {
      issues.push(`启动时间超标: ${this.metrics.loadTime.toFixed(2)}ms > ${performanceTargets.maxStartupTime}ms`);
    }

    if (this.metrics.firstPaintTime && this.metrics.firstPaintTime > performanceTargets.maxFirstPaint) {
      issues.push(`首次绘制时间超标: ${this.metrics.firstPaintTime.toFixed(2)}ms > ${performanceTargets.maxFirstPaint}ms`);
    }

    if (issues.length > 0) {
      console.warn('[启动优化] 性能目标未达成:', issues);
    } else {
      console.log('[启动优化] 所有性能目标已达成');
    }
  }

  /**
   * 获取启动指标
   */
  getMetrics(): BootstrapMetrics {
    return { ...this.metrics };
  }

  /**
   * 获取启动阶段
   */
  getStartupPhase(): string {
    return this.startupPhase;
  }

  /**
   * 获取完成的任务列表
   */
  getCompletedTasks(): string[] {
    return Array.from(this.completedTasks);
  }

  /**
   * 获取待执行的任务列表
   */
  getPendingTasks(): string[] {
    return Array.from(this.deferredTasks.keys()).filter(name => !this.completedTasks.has(name));
  }

  /**
   * 强制执行特定的延迟任务
   */
  async forceExecuteTask(taskName: string): Promise<void> {
    const task = this.deferredTasks.get(taskName);
    if (!task) {
      throw new Error(`Task ${taskName} not found`);
    }

    if (this.completedTasks.has(taskName)) {
      console.warn(`[启动优化] 任务 ${taskName} 已完成`);
      return;
    }

    await this.executeDeferredTask(task);
  }

  /**
   * 生成性能报告
   */
  generatePerformanceReport(): {
    metrics: BootstrapMetrics;
    phase: string;
    completedTasks: string[];
    pendingTasks: string[];
    score: number;
    recommendations: string[];
  } {
    const score = this.calculatePerformanceScore();
    const recommendations = this.generateRecommendations();

    return {
      metrics: this.getMetrics(),
      phase: this.getStartupPhase(),
      completedTasks: this.getCompletedTasks(),
      pendingTasks: this.getPendingTasks(),
      score,
      recommendations
    };
  }

  /**
   * 计算性能分数
   */
  private calculatePerformanceScore(): number {
    let score = 100;
    const { performanceTargets } = this.config;

    // 启动时间扣分
    if (this.metrics.loadTime) {
      const startupRatio = this.metrics.loadTime / performanceTargets.maxStartupTime;
      if (startupRatio > 1) {
        score -= Math.min(30, (startupRatio - 1) * 30);
      }
    }

    // 首次绘制时间扣分
    if (this.metrics.firstPaintTime) {
      const paintRatio = this.metrics.firstPaintTime / performanceTargets.maxFirstPaint;
      if (paintRatio > 1) {
        score -= Math.min(20, (paintRatio - 1) * 20);
      }
    }

    // 任务完成率加分/扣分
    const totalTasks = this.deferredTasks.size;
    const completedRatio = this.completedTasks.size / totalTasks;
    if (completedRatio < 0.8) {
      score -= (0.8 - completedRatio) * 25;
    }

    return Math.max(0, Math.round(score));
  }

  /**
   * 生成优化建议
   */
  private generateRecommendations(): string[] {
    const recommendations: string[] = [];
    const { performanceTargets } = this.config;

    if (this.metrics.loadTime && this.metrics.loadTime > performanceTargets.maxStartupTime) {
      recommendations.push('优化关键组件加载，减少启动时间');
      recommendations.push('考虑使用代码分割和懒加载');
    }

    if (this.metrics.firstPaintTime && this.metrics.firstPaintTime > performanceTargets.maxFirstPaint) {
      recommendations.push('优化CSS和JavaScript加载顺序');
      recommendations.push('减少阻塞渲染的资源');
    }

    if (this.getPendingTasks().length > 0) {
      recommendations.push('检查延迟任务的执行条件和依赖');
    }

    if (recommendations.length === 0) {
      recommendations.push('启动性能良好，继续保持');
    }

    return recommendations;
  }
}

// 默认配置
export const defaultBootstrapConfig: BootstrapConfig = {
  criticalComponents: [
    'Router',
    'StateProvider',
    'Layout',
    'Navigation'
  ],
  preloadRoutes: [
    '/',
    '/text',
    '/text/editor'
  ],
  deferredInitialization: [
    {
      name: 'AnalyticsService',
      priority: 1,
      initialize: async () => {
        console.log('[延迟任务] 初始化分析服务');
        await new Promise(resolve => setTimeout(resolve, 200));
      }
    },
    {
      name: 'ErrorReporting',
      priority: 2,
      initialize: async () => {
        console.log('[延迟任务] 初始化错误报告');
        await new Promise(resolve => setTimeout(resolve, 150));
      }
    },
    {
      name: 'PerformanceMonitoring',
      priority: 3,
      initialize: async () => {
        console.log('[延迟任务] 初始化性能监控');
        await new Promise(resolve => setTimeout(resolve, 100));
      }
    }
  ],
  cacheStrategy: {
    enableServiceWorker: false, // Electron 环境中通常不需要
    enableStaticCaching: true,
    enableDynamicCaching: true,
    cacheVersion: '1.0.0',
    maxCacheSize: 50
  },
  performanceTargets: {
    maxStartupTime: 3000, // 3秒
    maxTimeToInteractive: 5000, // 5秒
    maxFirstPaint: 1500 // 1.5秒
  }
};